<template>
  <div class="cal_con">
    <div class="cal_header">
      <div class="cal_h_btn_box">
        <span class="cal_h_time"> 年 </span>
        <span class="cal_h_time"> 月</span>
      </div>
    </div>
    <div class="cal_m_weeks">
      <span v-for="w in weeks" :key="w" class="cal_m_day_cell box"></span>
    </div>
    <div
      class="cal_month"
      ref="date_box"
      :style="{ ...slideStyle }"
      v-swipeup="(e) => vueTouch('上滑', e)"
      v-swipedown="(e) => vueTouch('下滑', e)"
    >
      <div class="height"></div>
      <div class="cal_m_days">
        <div
          v-for="(ds, index) in monthData"
          :key="index"
          class="cal_m_day_line"
        >
          <div
            v-for="d in ds"
            :key="d.day"
            :class="{
              cal_m_day_cell: d.type === 0,
            }"
            class="cal_m_day_cell2"
            :style="{ ...defatulCellColor(d), ...selectStyle(d) }"
            @click="mouseenter(d)"
          >
            
          </div>
        </div>
      </div>
      <div class="height"></div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Calendar",
  props: {
    date: {
      type: Date,
      default: () => new Date(),
    },
    mode: {
      type: String,
      default: "multiple",
    },
    type: {
      type: String,
      default: "switch",
    },
  },
  data() {
    return {
      boxTop: 0,
      selectClass: {
        color: "#fff",
        borderRadius: "4px",
        background: "#3374ff",
      },
      rangeClass: {
        color: "#fff",
        borderRadius: "0px",
        background: "rgb(51, 116, 255,0.45)",
      },
      now: this.date,
      year: 0,
      month: 0,
      weeks: ["日", "一", "二", "三", "四", "五", "六"],
      monthData: [],
      currentYear: new Date().getFullYear(),
      currentMonth: new Date().getMonth() + 1,
      currentDay: new Date().getDate(),
      selectDay: [],
    };
  },
  computed: {
    slideStyle() {
      if (this.type === "slide") {
        return {
          height: "292px",
          overflow: "auto",
        };
      }
    },
    nextColor() {
      return (d) => {
        let color =
          d.type == -1 ? "transparent" : d.type == 1 ? "transparent" : "";
        let visibility = d.type == -1 ? "hiden" : d.type == 1 ? "hiden" : "";
        let opacity = d.type == -1 ? 0 : d.type == 1 ? 0 : "";
        return {
          color,
          visibility,
          opacity,
        };
      };
    },
    defatulCellColor() {
      return (d) => {
        let color =
          d.type == -1 ? "transparent" : d.type == 1 ? "transparent" : "";
        let visibility = d.type == -1 ? "hiden" : d.type == 1 ? "hiden" : "";
        let opacity = d.type == -1 ? 0 : d.type == 1 ? 0 : "";
        return {
          color,
          visibility,
          opacity,
        };
      };
    },
    selectStyle() {
      return (d) => {
        if (this.mode === "select" || this.mode === "multiple") {
          if (d.isSelcet) {
            return this.selectClass;
          } else {
            return {};
          }
        } else {
          if (this.selectDay.length) {
            let currentYear = d.fullYear;
            let currentMonth = d.month >= 10 ? d.month : "0" + d.month;
            let currentDay = d.day >= 10 ? d.day : "0" + d.day;
            let currentDate = `${currentYear}${currentMonth}${currentDay}`;
            let startYear = this.selectDay[0].fullYear;
            let startMonth =
              this.selectDay[0].month >= 10
                ? this.selectDay[0].month
                : "0" + this.selectDay[0].month;
            let startDay =
              this.selectDay[0].day >= 10
                ? this.selectDay[0].day
                : "0" + this.selectDay[0].day;
            let startDate = `${startYear}${startMonth}${startDay}`;
            let endYear = this.selectDay[this.selectDay.length - 1].fullYear;
            let endMonth =
              this.selectDay[this.selectDay.length - 1].month >= 10
                ? this.selectDay[this.selectDay.length - 1].month
                : "0" + this.selectDay[this.selectDay.length - 1].month;
            let endDay =
              this.selectDay[this.selectDay.length - 1].day >= 10
                ? this.selectDay[this.selectDay.length - 1].day
                : "0" + this.selectDay[this.selectDay.length - 1].day;
            let endDate = `${endYear}${endMonth}${endDay}`;
            if (Number(currentDate) === Number(startDate) && d.isSelcet) {
              console.log(1);
              return this.selectClass;
            } else if (Number(currentDate) === Number(endDate) && d.isSelcet) {
              console.log(2);
              return this.selectClass;
            } else if (
              Number(endDate) > Number(currentDate) &&
              Number(currentDate) > Number(startDate)
            ) {
              console.log("<<<<<<<<<", endDate, "jieshu");
              console.log(currentDate, "dangqian");
              console.log(currentDate, "kaishi", ">>>>>>>>>>");
              return this.rangeClass;
            } else {
              return {};
            }
          } else {
            return {};
          }
        }
      };
    },
  },
  mounted() {
    this.setYearMonth(this.now);
    this.generateMonth(this.now);
    this.$nextTick(() => {
      this.$refs["date_box"].scrollTop = 30;
    });
  },
  methods: {
    setYearMonth(now) {
      this.year = now.getFullYear();
      this.month = now.getMonth() + 1;
    },
    vueTouch: function (txt, e) {
      if (txt === "上滑") {
        this.nextMonth();
        this.$nextTick(() => {
          this.$refs["date_box"].scrollTop = 30;
        });
      } else if (txt === "下滑") {
        this.preMonth();
        this.$nextTick(() => {
          this.$refs["date_box"].scrollTop = 30;
        });
      }
    },
    preYear() {
      let n = this.now;
      let date = new Date(
        n.getFullYear() - 1,
        n.getMonth(),
        n.getDate(),
        n.getHours(),
        n.getMinutes(),
        n.getSeconds(),
        n.getMilliseconds()
      );

      this.setYearMonthInfos(date);
    },
    preMonth() {
      let n = this.now;
      let date = new Date(
        n.getFullYear(),
        n.getMonth() - 1,
        n.getDate(),
        n.getHours(),
        n.getMinutes(),
        n.getSeconds(),
        n.getMilliseconds()
      );
      this.setYearMonthInfos(date);
    },
    nextYear() {
      let n = this.now;
      let date = new Date(
        n.getFullYear() + 1,
        n.getMonth(),
        n.getDate(),
        n.getHours(),
        n.getMinutes(),
        n.getSeconds(),
        n.getMilliseconds()
      );

      this.setYearMonthInfos(date);
    },
    nextMonth() {
      let n = this.now;
      let date = new Date(
        n.getFullYear(),
        n.getMonth() + 1,
        n.getDate(),
        n.getHours(),
        n.getMinutes(),
        n.getSeconds(),
        n.getMilliseconds()
      );
      this.setYearMonthInfos(date);
    },
    setYearMonthInfos(date) {
      this.setYearMonth(date);
      this.generateMonth(date);
      this.now = date;
      this.dateChange();
    },
    generateMonth(date) {
      date.setDate(1);
      // 星期 0 - 6， 星期天 - 星期6
      let weekStart = date.getDay();

      let endDate = new Date(date.getFullYear(), date.getMonth() + 1, 0);
      let dayEnd = endDate.getDate();
      // 星期 0 - 6， 星期天 - 星期6
      let weeEnd = endDate.getDay();

      let milsStart = date.getTime();
      let dayMils = 24 * 60 * 60 * 1000;
      let milsEnd = endDate.getTime() + dayMils;

      let monthDatas = [];
      let current;
      // 上个月的几天
      for (let i = 0; i < weekStart; i++) {
        current = new Date(milsStart - (weekStart - i) * dayMils);
        monthDatas.push({
          type: -1,
          date: current,
          fullYear: current.getFullYear(),
          month: current.getMonth() + 1,
          day: current.getDate(),
          isSelcet: false,
        });
      }
      // 当前月
      for (let i = 0; i < dayEnd; i++) {
        current = new Date(milsStart + i * dayMils);
        monthDatas.push({
          type: 0,
          date: current,
          fullYear: current.getFullYear(),
          month: current.getMonth() + 1,
          day: current.getDate(),
          isSelcet: false,
        });
      }
      // 下个月的几天
      for (let i = 0; i < 6 - weeEnd; i++) {
        current = new Date(milsEnd + i * dayMils);
        monthDatas.push({
          type: 1,
          date: current,
          fullYear: current.getFullYear(),
          month: current.getMonth() + 1,
          day: current.getDate(),
          isSelcet: false,
        });
      }

      this.monthData = [];
      for (let i = 0; i < monthDatas.length; i++) {
        let mi = i % 7;
        if (mi == 0) {
          this.monthData.push([]);
        }
        this.monthData[Math.floor(i / 7)].push(monthDatas[i]);
      }
    },
    clickRange(d) {
      if (
        Number(
          `${this.selectDay[1].fullYear}${this.selectDay[1].month}${this.selectDay[1].day}`
        ) < Number(`${d.fullYear}${d.month}${d.day}`) ||
        Number(
          `${this.selectDay[1].fullYear}${this.selectDay[0].month}${this.selectDay[0].day}`
        ) < Number(`${d.fullYear}${d.month}${d.day}`)
      ) {
        let day = this.selectDay.pop();
        day.isSelcet = false;
        this.selectDay.push(d);
      } else if (
        Number(
          `${this.selectDay[0].fullYear}${this.selectDay[0].month}${this.selectDay[0].day}`
        ) > Number(`${d.fullYear}${d.month}${d.day}`)
      ) {
        let day = this.selectDay.shift();
        day.isSelcet = false;
        this.selectDay.unshift(d);
      }
      console.log(this.selectDay);
    },
    mouseenter(d, event) {
      d.isSelcet = !d.isSelcet;
      if (d.isSelcet) {
        if (this.mode === "select") {
          this.selectDay.push(d);
          if (this.selectDay.length > 1) {
            this.selectDay.forEach((item, index) => {
              if (
                `${item.fullYear}${item.month}${item.day}` ===
                  `${d.fullYear}${d.month}${d.day}` &&
                d.isSelcet
              ) {
                item.isSelcet = ture;
              } else {
                item.isSelcet = false;
                this.selectDay.splice(index, 1);
              }
            });
          }
        } else if (this.mode === "multiple") {
          this.selectDay = [...new Set(this.selectDay)];
        } else {
          if (this.selectDay.length === 2) {
            this.clickRange(d);
          } else {
            if (this.selectDay.length === 1) {
              let currentYear = d.fullYear;
              let currentMonth = d.month >= 10 ? d.month : "0" + d.month;
              let currentDay = d.day >= 10 ? d.day : "0" + d.day;
              let currentDate = `${currentYear}${currentMonth}${currentDay}`;
              let endYear = this.selectDay[this.selectDay.length - 1].fullYear;
              let endMonth =
                this.selectDay[this.selectDay.length - 1].month >= 10
                  ? this.selectDay[this.selectDay.length - 1].month
                  : "0" + this.selectDay[this.selectDay.length - 1].month;
              let endDay =
                this.selectDay[this.selectDay.length - 1].day >= 10
                  ? this.selectDay[this.selectDay.length - 1].day
                  : "0" + this.selectDay[this.selectDay.length - 1].day;
              let endDate = `${endYear}${endMonth}${endDay}`;
              if (currentDate < endDate) {
                this.selectDay.unshift(d);
              } else {
                this.selectDay.push(d);
              }
            } else {
              this.selectDay.push(d);
            }
          }
        }
      } else {
        let index = this.selectDay.findIndex((item) => {
          return (
            `${item.fullYear}${item.month}${item.day}` ===
            `${d.fullYear}${d.month}${d.day}`
          );
        });
        if (index >= 0) {
          this.selectDay.splice(index, 1);
        }
      }
      this.$emit("enter", event, this.selectDay);
    },
    dateChange() {
      let fullYear = this.now.getFullYear();
      let month = this.now.getMonth();

      let startDay = new Date(fullYear, month, 1);
      let endDay = new Date(fullYear, month + 1, 0, 23, 59, 59);

      this.$emit("changeMonth", startDay, endDay);
    },
  },
  watch: {
    monthData: {
      // 数据变化时执行的逻辑代码
      handler(newName, oldName) {
        newName.forEach((it) => {
          it.forEach((item) => {
            this.selectDay.forEach((sIt) => {
              if (
                `${sIt.fullYear}${sIt.month}${sIt.day}` ===
                `${item.fullYear}${item.month}${item.day}`
              ) {
                item.isSelcet = sIt.isSelcet;
              }
            });
          });
        });
      },
      // 开启深度监听
      deep: true,
    },
    // boxTop: {
    //   handler(newValue) {
    //     console.log(newValue);
    //     if (newValue <= 50) {
    //       this.monthData = [];
    //       this.preMonth();
    //       this.dateArr.unshift(this.monthData);
    //     } else if (newValue >= this.dateArr.length * 270 - 540) {
    //       this.monthData = [];
    //       let date = new Date(
    //         n.getFullYear(),
    //         n.getMonth() + 1,
    //         n.getDate(),
    //         n.getHours(),
    //         n.getMinutes(),
    //         n.getSeconds(),
    //         n.getMilliseconds()
    //       );
    //       this.generateMonth(date);
    //       this.dateArr.push(this.monthData);
    //     }
    //   },
    // },
  },
};
</script>

<style scoped lang="less">
.cal_con {
  width: 100%;
  height: 100%;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;

  color: #606266;
  // border: 1px solid #e4e7ed;
  // box-shadow: 0 2px 12px 0 #0000006e;
  background: #fff;
  // border-radius: 4px;
  margin: auto;

  .cal_header {
    width: 100%;
    height: 44px;
    padding: 0 5px;
    font-size: 14px;
    line-height: 44px;
    display: flex;
    justify-content: space-between;
    justify-items: center;
    .cal_h_btn_box {
      width: 100%;
      text-align: center;
    }

    .cal_h_time {
      cursor: pointer;
    }
    .cal_h_time:hover {
      color: #409eff;
    }

    .cal_h_left {
      height: 100%;
      display: flex;

      .cal_h_btn {
        height: 100%;
        cursor: pointer;
      }

      // .cal_h_btn:hover {
      //   background-color: #ebeef5;
      // }

      .cal_h_l_icon {
        height: 8px;
        width: 12px;
        margin: auto;
      }
    }
    .cal_h_right {
      text-align: right;
    }
  }
  .cal_month {
    font-size: 12px;
    text-align: center;
    height: calc(100% - 34px);

    .cal_m_day_cell {
      width: 54px;
      height: 54px;
      line-height: 54px;
      cursor: pointer;
      position: relative;
    }
    .cal_m_day_cell2 {
      width: 54px;
      height: 54px;
      line-height: 54px;
      cursor: pointer;
      position: relative;
    }
    // .cal_m_day_cell:hover {
    //   color: #fff;

    //   border-radius: 4px;
    // }

    .cal_m_days {
      padding: 0 8px;
      display: flex;
      justify-content: space-around;
      justify-items: center;
      flex-wrap: wrap;
      .cal_m_day_line {
        width: 100%;
        display: flex;
        justify-content: space-around;
        justify-items: center;
      }
    }
  }
  .cal_m_weeks {
    height: 30px;
    display: flex;
    justify-content: space-around;
    justify-items: center;
    .box {
      width: 54px;
      height: 54px;
      line-height: 54px;
      cursor: pointer;
      text-align: center;
      position: relative;
    }
    // box-shadow: 0 0px 12px 0 #0000006e;
  }
}
.top_weeks {
  position: sticky;
  top: 0px;
}
.height {
  width: 30px;
  height: 30px;
}
</style>
